package com.mes.handler.plan;

import com.basis.utils.HibernateDao;
import com.mes.manufacture.data.EmesoManuOrder;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.openbravo.client.kernel.BaseActionHandler;
import org.openbravo.dal.core.OBContext;
import org.openbravo.dal.service.OBDal;
import java.util.*;

/**
 * 拉动计划生成计划开工时间
 */
public class ManuOrderGenerateTimeHandler extends BaseActionHandler {
	@Override
	protected JSONObject execute(Map<String, Object> parameters, String content) {
		JSONObject jsonRep = new JSONObject();
		String msg = "";
		try {
			//设置Admin权限
			OBContext.setAdminMode();
			jsonRep.put("flag", true);
			jsonRep.put("message", "处理成功");

			Calendar time = Calendar.getInstance();
			time.setTime(new Date());//获取当前系统时间
			time.set(Calendar.MINUTE, 0);
			time.set(Calendar.SECOND, 0);
			time.set(Calendar.MILLISECOND, 0);

			Date beginTime = time.getTime();
			time.set(Calendar.HOUR, time.get(Calendar.HOUR) + 1);

			//获取生产订单中所有未生产的拉动计划
			String sql = "select sc.qty, sc.priorty_level, dd.sales_date, sc.emeso_manuorder_id, sc.planed_date_from  " +
					"  from emeso_manuorder sc, wms_sales_order dd  " +
					" where sc.wms_sales_order_id = dd.wms_sales_order_id  " +
					"	and sc.status in ('CREATE', 'EXECUTING') " +
					" order BY sc.priorty_level, dd.sales_date ";

			List<Map<String, Object>> planList = HibernateDao.query(sql);

			if (planList == null || planList.isEmpty()) {
				throw new RuntimeException("当前拉动计划均已派工！");
			}

			int planCount = getNowTimeManuOrderCount(beginTime, time.getTime());
			int numbers = getHouseManuSize();

			long datetime = time.getTime().getTime();

			int qtys = 0;
			//当前计划时间内计划数量不满足小时计划产量
			if (numbers - planCount > 10) {
				qtys = planCount;
				datetime = beginTime.getTime();
			} else {
				//处理查询时间段条件
				beginTime = time.getTime();
			}

			EmesoManuOrder order = null;
			for (Map<String, Object> map : planList) {
				order = (EmesoManuOrder) OBDal.getInstance().get(EmesoManuOrder.ENTITY_NAME, map.get("EMESO_MANUORDER_ID"));

				order.setPlanedDateFrom(new Date(datetime + (numbers + qtys - 1) / numbers * 1000 * 3600));
				OBDal.getInstance().save(order);

				//获取生成订单的生产数量相加循环数量
				qtys += order.getQty().intValue();
			}

			OBDal.getInstance().flush();

			if ("".equals(msg)) {
				jsonRep.put("flag", true);
				jsonRep.put("message", "处理成功");

				time.set(Calendar.HOUR, time.get(Calendar.HOUR) + 1);
				Date endTime = time.getTime();
				//进行自动拍功能处理
				String orderIds = this.onKeyAssign(beginTime, endTime);//自动派工
				jsonRep.put("ids", orderIds);
				OBDal.getInstance().commitAndClose();
				return jsonRep;
			} else {
				jsonRep.put("flag", false);
				jsonRep.put("message", msg);
				OBDal.getInstance().rollbackAndClose();
				return jsonRep;
			}
		} catch (Exception e) {
			OBDal.getInstance().rollbackAndClose();
			e.printStackTrace();
			try {
				jsonRep.put("flag", false);
				jsonRep.put("message", e.getMessage());
				return jsonRep;
			} catch (Exception e2) {
			}
		} finally {
			OBContext.restorePreviousMode();
		}
		return null;
	}

	//查询最近一小时未派工订单信息
	private String onKeyAssign(Date beginTime, Date endTime) {
		String sql = " SELECT mo.emeso_manuorder_id id, wl.value pCode, wl.name pName, (mo.qty - nvl(mo.qty_assign, 0)) AS qtys, po.color " +
				"  FROM m_product wl, emesp_planorder po, emeso_manuorder mo " +
				" WHERE wl.m_product_id = mo.m_product_id" +
				"	and po.emesp_planorder_id = mo.emesp_planorder_id" +
				"	and mo.status in ('CREATE', 'EXECUTING')" +
				"	and mo.planed_date_from < ?";
		List<Map<String, Object>> list = HibernateDao.query(sql, endTime);
		return onKeyAssign(list);
	}

	/**
	 * 一键派工
	 * @param list
	 * @return
	 */
	public String onKeyAssign(List<Map<String, Object>> list) {
		StringBuilder ids = new StringBuilder();
		if (list != null && !list.isEmpty()) {
			String facId = null;
			JobOrderAssignHandler handler = new JobOrderAssignHandler();
			List<JSONObject> fzList = handler.getFzList();
			int qty = 0;

			for (Map<String, Object> map : list) {
				qty = Double.valueOf(map.get("qtys").toString()).intValue();
				for (int i = 0;i < qty;i ++) {
					//根据形体和颜色获取派工最少的飞织机ID
					facId = getFzjXTColorById(fzList, map.get("pcode") + "-" + map.get("color"), 1);
					if (facId != null) {
						handler.assignToFacilities((String) map.get("id"), facId, null, 1);
						ids.append(map.get("id")).append(",");
					}
				}
			}
		}
		return ids.toString();
	}

	//查询飞织机形体颜色
	public String getFzjXTColorById(List<JSONObject> fzList, String xtColor, int qty) {
		JSONArray colors = null;
		String id = null;
		int minQty = -1;
		JSONObject minJson = null;

		for (JSONObject json : fzList) {
			try {
				//非正常运行设备则不做计算
				if (!"RUN".equals(json.getString("run_status"))) {
					continue;
				}
				colors = json.getJSONArray("colors");
				for (int i = 0;i < colors.length(); i ++) {
					String color = colors.getJSONObject(i).getString("pcode") + "-" + colors.getJSONObject(i).getString("name");

					//判断形体和颜色相同
					if (color.equals(xtColor)) {
						//比较哪台飞织机的已派工数量最少
						if (minQty == -1 || json.getInt("count") < minQty) {
							id = json.getString("id");
							minQty = json.getInt("count");
							minJson = json;
						}
					}
				}
			} catch (Exception e) {
			}
		}
		//修改派工飞织机的已派工数量
		if (minJson != null) {
			try {
				minJson.put("count", minQty + qty);
			} catch (Exception e) {
			}
		}
		return id;
	}

	//查询当前时间段已生成多少作业拉动计划
	private int getNowTimeManuOrderCount(Date beginTime, Date endTime) {
		String sql = "select sum(qty) qty from emeso_manuorder where planed_date_from >= ? and planed_date_from < ?";
		Map<String, Object> result = HibernateDao.queryUnique(sql, beginTime, endTime);
		if (result != null && result.get("qty") != null) {
			return Double.valueOf(result.get("qty").toString()).intValue();
		}
		return 0;
	}

	//获取配置参数中小时计划数量
	private int getHouseManuSize() {
		//获取MES参数中一个小时的生产数量
		String aql = " select cs.VALUE from Emes_Parameter cs where cs.code = 'PATH1909200001'";
		List<Map<String, Object>> result = HibernateDao.query(aql);
		for (Map<String, Object> map : result) {
			try {
				return Integer.parseInt(map.get("VALUE").toString());
			} catch (Exception e) {
			}
		}
		return 30;
	}
}
